/*
 *  NodeGrid.cpp
 *  cocos3d-x
 *
 *  Created by Yezhiyong on 12-4-26.
 *  Copyright 2012 __MyCompanyName__. All rights reserved.
 *
 */

#include "NodeGrid.h"

NodeGrid* NodeGrid::nodeWithName(const char* aName)
{
	NodeGrid* pGrid = new NodeGrid;
	if (pGrid) 
	{
		pGrid->initWithName(aName);
		pGrid->autorelease();
	}
	
	return pGrid;
}

void NodeGrid::populateWith(CC3Node* templateNode, unsigned int perSideCount)
{
	removeAllChildren();	// Get rid of any existing children
	
	// To help demonstrate that the hordes of nodes are being managed correctly,
	// log the current number of nodes, before the new nodes have been created.
	//LogInfo(@"Before populating %@ with %u copies of %@ there are %i instances of CC3Identifiable subclasses in existance.",
//			self, (perSideCount * perSideCount), templateNode, [CC3Identifiable instanceCount]);
	
	switch (perSideCount) 
	{
		case 0:				// If we don't want any nodes, just leave
			break;
		case 1: 
		{			// For one node, just place the single copy at the origin
			CC3Node* aNode = templateNode;
			aNode->retain();//[templateNode copyAutoreleased];
			aNode->setLocation(kCC3VectorZero);
			aNode->setUniformScale(aNode->getUniformScale() * 2);
			addChild(aNode);
			break;
		}
		default: 
		{			// Otherwise...lay out a grid of copies
			GLfloat sideLength = 100.0f;
			GLfloat spacing = sideLength / (perSideCount - 1);
			GLfloat xOrg = -sideLength / 2.0f;
			GLfloat zOrg = -sideLength / 2.0f;
			
			// Scale the node down as the number grows larger, using 3 nodes per side as the standard scale
			GLfloat scaleFactor = 5.0f / (perSideCount * 2 - 1);
			
			// Create many copies (perSideCount ^ 2), and space them out in a grid pattern.
			for (int ix = 0; ix < perSideCount; ix++) 
			{
				for (int iz = 0; iz < perSideCount; iz++) 
				{
					GLfloat xLoc = xOrg + spacing * ix;
					GLfloat zLoc = zOrg + spacing * iz;
					
					CC3Node* aNode = templateNode;//[templateNode copyAutoreleased];
					aNode->retain();
					aNode->setLocation(cc3v(xLoc, 0.0f, zLoc));
					aNode->setUniformScale(aNode->getUniformScale() * scaleFactor);
					addChild(aNode);
				}
			}
			break;
		}
	}
	
	createGLBuffers();			// Copy vertex data to OpenGL VBO's.
	releaseRedundantData();	// Release vertex data from main memory.
	
	// To help demonstrate that the hordes of nodes are being managed correctly,
	// log the current number of nodes, before the new nodes have been created.
	//LogInfo(@"After populating %@ there are %i instances of CC3Identifiable subclasses in existance.",
//			self, [CC3Identifiable instanceCount]);
}